﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace System
{
    public class ReflectionHelper
    {
        public static string GetDisplayName(Type t)
        {
            var dna = t.GetCustomAttribute<System.ComponentModel.DisplayNameAttribute>(true);
            if (dna != null)
            {
                return dna.DisplayName;
            }
            return null;
        }
        public static string GetDisplayName(PropertyInfo p)
        {
            var dna = p.GetCustomAttribute<System.ComponentModel.DisplayNameAttribute>(true);
            if (dna != null)
            {
                return dna.DisplayName;
            }
            return null;
        }
        public static string GetDescription(Type t)
        {
            var da = t.GetCustomAttribute<System.ComponentModel.DescriptionAttribute>(true);
            if (da != null)
            {
                return da.Description;
            }
            return null;
        }
        public static string GetDescription(PropertyInfo p)
        {
            var da = p.GetCustomAttribute<System.ComponentModel.DescriptionAttribute>(true);
            if (da != null)
            {
                return da.Description;
            }
            return null;
        }
        /// <summary>
        /// 获取类型中标注了<see cref="System.ComponentModel.DisplayNameAttribute"/>的属性
        /// </summary>
        /// <param name="t"></param>
        /// <param name="sortByAttr">是否使用<see cref="System.ComponentModel.SortIndexAttribute"/>对返回的结果进行排序</param>
        /// <param name="bindingFlags"></param>
        /// <returns></returns>
        public static Dictionary<PropertyInfo, string> GetPropertiesWidthDisplayName(Type t, bool sortByAttr = true, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
        {
            PropertyInfo[] ps;
            if (sortByAttr)
            {
                ps = GetPropertiesBySortIndex(t, bindingFlags);
            }
            else
            {
                ps = t.GetProperties(bindingFlags);
            }

            Dictionary<PropertyInfo, string> result = new Dictionary<PropertyInfo, string>();
            foreach (var p in ps)
            {
                var dna = p.GetCustomAttribute<System.ComponentModel.DisplayNameAttribute>();
                if (dna != null)
                {
                    result.Add(p, dna.DisplayName);
                }
            }
            return result;
        }
        /// <summary>
        /// 根据属性定义的<see cref="System.ComponentModel.SortIndexAttribute"/>的顺序来获取指定类型的属性列表
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static PropertyInfo[] GetPropertiesBySortIndex(Type t, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
        {
            var ps = t.GetProperties(bindingFlags);
            List<KeyValuePair<PropertyInfo, int>> pairs = new List<KeyValuePair<PropertyInfo, int>>();

            foreach (var item in ps)
            {
                var sia = item.GetCustomAttribute<System.ComponentModel.SortIndexAttribute>();
                if (sia != null)
                {
                    pairs.Add(new KeyValuePair<PropertyInfo, int>(item, sia.SortIndex));
                }
                else
                {
                    pairs.Add(new KeyValuePair<PropertyInfo, int>(item, int.MaxValue));
                }
            }
            pairs.Sort(new Comparison<KeyValuePair<PropertyInfo, int>>(
                (kv1, kv2) => kv1.Value - kv2.Value
                ));
            List<PropertyInfo> result = new List<PropertyInfo>();
            foreach (var pair in pairs)
            {
                result.Add(pair.Key);
            }
            return result.ToArray();
        }
    }
}
